home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Add-Ons / MPW / MPW cawf 4.0.9 / nreq.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-01  |  21.6 KB  |  1,142 lines  |  [TEXT/KAHL]

  1. /*
  2.  *    nreq.c - cawf(1) processing of nroff requests
  3.  */
  4.  
  5. /*
  6.  *    Copyright (c) 1991 Purdue University Research Foundation,
  7.  *    West Lafayette, Indiana 47907.  All rights reserved.
  8.  *
  9.  *    Written by Victor A. Abell <abe@cc.purdue.edu>,  Purdue    University
  10.  *    Computing Center.  Not derived from licensed software; derived from
  11.  *    awf(1) by Henry Spencer of the University of Toronto.
  12.  *
  13.  *    Permission is granted to anyone to use this software for any
  14.  *    purpose on any computer system, and to alter it and redistribute
  15.  *    it freely, subject to the following restrictions:
  16.  *
  17.  *    1. The author is not responsible for any consequences of use of
  18.  *       this software, even if they arise from flaws in it.
  19.  *
  20.  *    2. The origin of this software must not be misrepresented, either
  21.  *       by explicit claim or by omission.  Credits must appear in the
  22.  *       documentation.
  23.  *
  24.  *    3. Altered versions must be plainly marked as such, and must not
  25.  *       be misrepresented as being the original software.  Credits must
  26.  *       appear in the documentation.
  27.  *
  28.  *    4. This notice may not be removed or altered.
  29.  */
  30.  
  31. #include "cawf.h"
  32. #include <ctype.h>
  33.  
  34.  
  35. /*
  36.  * Prototypes for request processing functions.
  37.  */
  38.  
  39. _PROTOTYPE(static void nr_UL,(unsigned char *line, int brk));
  40. _PROTOTYPE(static void nr_Ub,(unsigned char *line, int brk));
  41. _PROTOTYPE(static void nr_Uc,(unsigned char *line, int brk));
  42. _PROTOTYPE(static void nr_Uf,(unsigned char *line, int brk));
  43. _PROTOTYPE(static void nr_Ur,(unsigned char *line, int brk));
  44. _PROTOTYPE(static void nr_ad,(unsigned char *line, int brk));
  45. _PROTOTYPE(static void nr_bp,(unsigned char *line, int brk));
  46. _PROTOTYPE(static void nr_br,(unsigned char *line, int brk));
  47. _PROTOTYPE(static void nr_ce,(unsigned char *line, int brk));
  48. _PROTOTYPE(static void nr_di,(unsigned char *line, int brk));
  49. _PROTOTYPE(static void nr_ds,(unsigned char *line, int brk));
  50. _PROTOTYPE(static void nr_fi,(unsigned char *line, int brk));
  51. _PROTOTYPE(static void nr_fl,(unsigned char *line, int brk));
  52. _PROTOTYPE(static void nr_ft,(unsigned char *line, int brk));
  53. _PROTOTYPE(static void nr_it,(unsigned char *line, int brk));
  54. _PROTOTYPE(static void nr_na,(unsigned char *line, int brk));
  55. _PROTOTYPE(static void nr_nf,(unsigned char *line, int brk));
  56. _PROTOTYPE(static void nr_ns,(unsigned char *line, int brk));
  57. _PROTOTYPE(static void nr_rm,(unsigned char *line, int brk));
  58. _PROTOTYPE(static void nr_rn,(unsigned char *line, int brk));
  59. _PROTOTYPE(static void nr_rr,(unsigned char *line, int brk));
  60. _PROTOTYPE(static void nr_rs,(unsigned char *line, int brk));
  61. _PROTOTYPE(static void nr_tl,(unsigned char *line, int brk));
  62. _PROTOTYPE(static void nr_tm,(unsigned char *line, int brk));
  63. _PROTOTYPE(static void nr_tr,(unsigned char *line, int brk));
  64.  
  65. _PROTOTYPE(static void nr_nil,(unsigned char *line, int brk));
  66.  
  67.  
  68. /*
  69.  * NrReqt[] - nroff request processing table
  70.  *
  71.  * CAUTION: place new entries in their proper alphabetical order, since
  72.  *        this table is processed with a binary search.
  73.  */
  74.  
  75. static struct nr_req {
  76.     char *nm;            /* nroff request */
  77.     void (*fun)();            /* processing function */
  78. } NrReqt[] = {
  79.     { "\\\"",    nr_nil },    /* backslash-quote */
  80.     { "^#",        nr_UL  },
  81.     { "^=",        nr_UL  },
  82.     { "^b",        nr_Ub  },
  83.     { "^c",        nr_Uc  },
  84.     { "^d",        nr_nil },
  85.     { "^e",        nr_nil },
  86.     { "^f",        nr_Uf  },
  87.     { "^r",        nr_Ur  },
  88.     { "^x",        nr_nil },
  89.     { "ad",        nr_ad  },
  90.     { "bp",        nr_bp  },
  91.     { "br",        nr_br  },
  92.     { "ce",        nr_ce  },
  93.     { "di",        nr_di  },
  94.     { "ds",        nr_ds  },
  95.     { "fi",        nr_fi  },
  96.     { "fl",        nr_fl  },
  97.     { "ft",        nr_ft  },
  98.     { "i0",        nr_nil },
  99.     { "it",        nr_it  },
  100.     { "lg",        nr_nil },
  101.     { "li",        nr_nil },
  102.     { "na",        nr_na  },
  103.     { "nf",        nr_nf  },
  104.     { "ns",        nr_ns  },
  105.     { "ps",        nr_nil },
  106.     { "rm",        nr_rm  },
  107.     { "rn",        nr_rn  },
  108.     { "rr",        nr_rr  },
  109.     { "rs",        nr_rs  },
  110.     { "tl",        nr_tl  },
  111.     { "tm",        nr_tm  },
  112.     { "tr",        nr_tr  },
  113.     { "vs",        nr_nil },
  114. };
  115. /*
  116.  * Nreq(line, brk) - process miscellaneous nroff requests from line
  117.  *             buffer with request status of (brk)
  118.  */
  119.  
  120. void
  121. Nreq(line, brk)
  122.     unsigned char *line;
  123.     int brk;
  124. {
  125.     unsigned char c[3];        /* command buffer */
  126.     int cmp, hi, low, mid;        /* binary search indixes */
  127.  
  128.     c[0] = c[1] = c[2] = '\0';
  129.     if ((c[0] = line[1]) != '\0')
  130.         c[1] = line[2];
  131.  
  132.     low = mid = 0;
  133.     hi = (sizeof(NrReqt) / sizeof(struct nr_req)) - 1;
  134.     while (low <= hi) {
  135.         mid = (low + hi) / 2;
  136.         if ((cmp = strcmp((char *)c, NrReqt[mid].nm)) < 0)
  137.             hi = mid - 1;
  138.         else if (cmp > 0)
  139.             low = mid + 1;
  140.         else {
  141.  
  142. #if    defined(_BCC)
  143. #pragma warn -pro
  144. #endif    /* defined(_BCC) */
  145.  
  146.             (void) (*NrReqt[mid].fun)(line, brk);
  147.  
  148. #if    defined(_BCC)
  149. #pragma warn -pro
  150. #endif    /* defined(_BCC) */
  151.  
  152.             return;
  153.         }
  154.     }
  155.     /*
  156.      * Unknown request starting with a '.' or '\''..
  157.      */
  158.     Error(WARN, LINE, " unknown request", NULL);
  159. }
  160.  
  161.  
  162. /*
  163.  * Adjust - "^[.']ad"
  164.  */
  165.  
  166. #if    defined(_BCC)
  167. #pragma    argsused
  168. #endif    /* defined(_BCC) */
  169.  
  170. static void
  171. nr_ad(line, brk)
  172.     unsigned char *line;
  173.     int brk;
  174. {
  175.     Pass3(NOBREAK, (unsigned char *)"both", -1, NULL, 0);
  176. }
  177.  
  178.  
  179. /*
  180. * Begin new page - "^[.']bp"
  181. */
  182.  
  183. #if    defined(_BCC)
  184. #pragma    argsused
  185. #endif    /* defined(BCC) */
  186.  
  187.  
  188. static void
  189. nr_bp(line, brk)
  190.     unsigned char *line;
  191.     int brk;
  192. {
  193.     Pass3(brk, (unsigned char *)"need", -1, NULL, 999);
  194. }
  195.  
  196.  
  197. /*
  198. * Break - "^[.']br"
  199. */
  200.  
  201. #if    defined(_BCC)
  202. #pragma    argsused
  203. #endif    /* defined(BCC) */
  204.  
  205.  
  206. static void
  207. nr_br(line, brk)
  208.     unsigned char *line;
  209.     int brk;
  210. {
  211.     Pass3(brk, (unsigned char *)"flush", -1, NULL, 0);
  212. }
  213.  
  214.  
  215. /*
  216.  * Center - "^[.']ce"
  217.  */
  218.  
  219. #if    defined(_BCC)
  220. #pragma    argsused
  221. #endif    /* defined(BCC) */
  222.  
  223.  
  224. static void
  225. nr_ce(line, brk)
  226.     unsigned char *line;
  227.     int brk;
  228. {
  229.     unsigned char *s;            /* string poiner */
  230.  
  231.     if ((s = Field(2, line, 0)) != NULL)
  232.         Centering = atoi((char *)s);
  233.     else
  234.         Centering = 1;
  235.     Pass3(brk, (unsigned char *)"flush", -1, NULL, 0);
  236. }
  237.  
  238.  
  239. /*
  240.  * Diversion on and off - "^[.']di"
  241.  */
  242.  
  243. #if    defined(_BCC)
  244. #pragma    argsused
  245. #endif    /* defined(BCC) */
  246.  
  247.  
  248. static void
  249. nr_di(line, brk)
  250.     unsigned char *line;
  251.     int brk;
  252. {
  253.     Pass3(DOBREAK, (unsigned char *)"flush", -1, NULL, 0);
  254.     Divert ^= 1;
  255. }
  256.  
  257.  
  258. /*
  259.  * Define string - "^[.']ds"
  260.  */
  261.  
  262. #if    defined(_BCC)
  263. #pragma    argsused
  264. #endif    /* defined(BCC) */
  265.  
  266.  
  267. static void
  268. nr_ds(line, brk)
  269.     unsigned char *line;
  270.     int brk;
  271. {
  272.     unsigned char buf[MAXLINE];    /* temporary buffer */
  273.     unsigned char nm[4], nm1[4];    /* name buffers */
  274.     unsigned char *s1, *s2, *s4,    /* temporary string pointers */
  275.                *s5;
  276.  
  277.     if (Asmname(&line[3], nm) == 0) {
  278.         Error(WARN, LINE, " no name", NULL);
  279.         return;
  280.     }
  281.     if ((s4 = Field(3, line, 0)) == NULL)
  282.         s4 = (unsigned char *)"";
  283. /*
  284.  * Convert "\\b" to '\b' and "\\\\" to '\\'.  Pass all other sequences,
  285.  * beginning with '\\', unmodified.
  286.  */
  287.     s1 = buf;
  288.     while ((s5 = (unsigned char *)strchr((char *)s4, '\\')) != NULL) {
  289.         while (s5 > s4)
  290.             *s1++ = *s4++;
  291.         s4 = ++s5;
  292.         if (*s5 == '\\')
  293.             *s1++ = '\\';
  294.         else if (*s5 == 'b')
  295.             *s1++ = '\b';
  296.         else {
  297.             *s1++ = '\\';
  298.             *s1++ = *s5;
  299.         }
  300.         if (*s4)
  301.             s4++;
  302.     }
  303.  
  304. #if    defined(_BCC)
  305. #pragma warn -pia
  306. #endif    /* defined(_BCC) */
  307.  
  308.     while (*s1++ = *s4++)
  309.         ;
  310.  
  311. #if    defined(_BCC)
  312. #pragma warn +pia
  313. #endif    /* defined(_BCC) */
  314.  
  315. /*
  316.  * Install the string and see if it's an indirect reference -- e.g.,
  317.  *
  318.  *    .ds S1 \*(S2
  319.  */
  320.     s2 = Findstr(nm, buf, 1);
  321.     while (*s2 == '\\' && *(s2 + 1) == '*') {
  322.         s2++;
  323.         (void) Asmcode(&s2, nm1);
  324.         s2 = Findstr(nm1, NULL, 0);
  325.     }
  326.     if (Hdft) {
  327.  
  328. /*
  329.  * Look for names LH, LF, CH, CF, RH, RF.
  330.  */
  331.         if ((nm[0]=='L' || nm[0]=='C' || nm[0]=='R')
  332.         &&  (nm[1]=='F' || nm[1]=='H')) {
  333.             (void) sprintf((char *)buf, "%s", (char *)nm);
  334.             Pass3(NOBREAK, buf, -1, s2, 0);
  335.         }
  336.     }
  337. }
  338.  
  339.  
  340.  
  341. /*
  342.  * Fill - "^[.']fi"
  343.  */
  344.  
  345. #if    defined(_BCC)
  346. #pragma    argsused
  347. #endif    /* defined(_BCC) */
  348.  
  349.  
  350. static void
  351. nr_fi(line, brk)
  352.     unsigned char *line;
  353.     int brk;
  354. {
  355.     Fill = 1;
  356.     Pass3(brk, (unsigned char *)"flush", -1, NULL, 0);
  357. }
  358.  
  359.  
  360. /*
  361.  * Flush - "^[.']fl"
  362.  */
  363.  
  364. #if    defined(_BCC)
  365. #pragma    argsused
  366. #endif    /* defined(_BCC) */
  367.  
  368.  
  369. static void
  370. nr_fl(line, brk)
  371.     unsigned char *line;
  372.     int brk;
  373. {
  374.     Pass3(brk, (unsigned char *)"flush", -1, NULL, 0);
  375. }
  376.  
  377.  
  378. /*
  379.  * Font - "^[.']ft <font_name>"
  380.  */
  381.  
  382. #if    defined(_BCC)
  383. #pragma    argsused
  384. #endif    /* defined(_BCC) */
  385.  
  386.  
  387. static void
  388. nr_ft(line, brk)
  389.     unsigned char *line;
  390.     int brk;
  391. {
  392.     int i;                /* temporary index */
  393.  
  394.     if (line[3] == '\0' || line[4] == '\0')
  395.         line[4] = 'P';
  396.     if (line[4] == 'P') {
  397.         Font[0] = Prevfont;
  398.         return;
  399.     }
  400.     for (i = 0; Fcode[i].nm; i++) {
  401.         if (Fcode[i].nm == line[4])
  402.         break;
  403.     }
  404.     if (Fcode[i].status == '\0') {
  405.         Error(WARN, LINE, " bad font code", NULL);
  406.         return;
  407.     }
  408.     Prevfont = Font[0];
  409.     Font[0] = line[4];
  410. }
  411.  
  412.  
  413. /*
  414.  * Input trap - "^[.']it [1 <request>]"
  415.  */
  416.  
  417. #if    defined(_BCC)
  418. #pragma    argsused
  419. #endif    /* defined(_BCC) */
  420.  
  421.  
  422. static void
  423. nr_it(line, brk)
  424.     unsigned char *line;
  425.     int brk;
  426.  
  427. {
  428.     unsigned char buf[MAXLINE];    /* temporary buffer */
  429.     unsigned char *s1, *s2;        /* temporary string pointers */
  430.  
  431.     if ((s1 = Field(2, line, 0)) == NULL) {
  432.         Free(&Aftnxt);
  433.         return;
  434.     }
  435.     if (atoi((char *)s1) != 1) {
  436.         Error(WARN, LINE, " first .it arg must be 1", NULL);
  437.         return;
  438.     }
  439.     if ((s2 = Field(3, line, 0)) == NULL)
  440.         Free(&Aftnxt);
  441.     else {
  442.         (void) sprintf((char *)buf, "%s,%s",
  443.             (Aftnxt == NULL) ? "" : (char *)Aftnxt,
  444.             (char *)s2);
  445.         Free(&Aftnxt);
  446.         Aftnxt = Newstr(buf);
  447.     }
  448. }
  449.  
  450.  
  451. /*
  452.  * Comment - "^[.']\\" - do nothing
  453.  *
  454.  * Debug - "^[.']\^d" - do nothing
  455.  *
  456.  * Finalization - "[.']\^e" - do nothing
  457.  *
  458.  * Error file - "^[.']\^x <name>" - do nothing
  459.  *
  460.  * "^[.']i0", "^[.']lg" and "^[.']li" - do nothing
  461.  *
  462.  * Point size - "^[.']ps" - do nothing
  463.  *
  464.  * Vertical spacing - "^[.']vs" - do nothing
  465.  *
  466.  */
  467.  
  468. #if    defined(_BCC)
  469. #pragma    argsused
  470. #endif    /* defined(_BCC) */
  471.  
  472.  
  473. static void
  474. nr_nil(line, brk)
  475.     unsigned char *line;
  476.     int brk;
  477. {
  478. }
  479.  
  480.  
  481. /*
  482.  * No adjust "^[.']na"
  483.  */
  484.  
  485. #if    defined(_BCC)
  486. #pragma    argsused
  487. #endif    /* defined(_BCC) */
  488.  
  489.  
  490. static void
  491. nr_na(line, brk)
  492.     unsigned char *line;
  493.     int brk;
  494. {
  495.     Pass3(NOBREAK, (unsigned char *)"left", -1, NULL, 0);
  496. }
  497.  
  498.  
  499. /*
  500.  * No fill - "^[.']nf"
  501.  */
  502.  
  503. #if    defined(_BCC)
  504. #pragma    argsused
  505. #endif    /* defined(_BCC) */
  506.  
  507.  
  508. static void
  509. nr_nf(line, brk)
  510.     unsigned char *line;
  511.     int brk;
  512. {
  513.     Fill = 0;
  514.     Pass3(brk, (unsigned char *)"flush", -1, NULL, 0);
  515. }
  516.  
  517.  
  518. /*
  519.  * No space - "^[.']ns"
  520.  */
  521.  
  522. #if    defined(_BCC)
  523. #pragma    argsused
  524. #endif    /* defined(_BCC) */
  525.  
  526.  
  527. static void
  528. nr_ns(line, brk)
  529.     unsigned char *line;
  530.     int brk;
  531. {
  532.     Pass3(NOBREAK, (unsigned char *)"nospace", -1, NULL, 0);
  533. }
  534.  
  535.  
  536. /*
  537.  * Remove macro or string - "^[.']rm"
  538.  */
  539.  
  540. #if    defined(_BCC)
  541. #pragma    argsused
  542. #endif    /* defined(_BCC) */
  543.  
  544.  
  545. static void
  546. nr_rm(line, brk)
  547.     unsigned char *line;
  548.     int brk;
  549. {
  550.     int i;                /* temporary index */
  551.     unsigned char nm[4];        /* name buffer */
  552.  
  553.     if (Asmname(&line[3], nm) == 0) {
  554.         Error(WARN, LINE, " no name", NULL);
  555.         return;
  556.     }
  557.     if ((i = Findmacro(nm, 0)) >= 0) {
  558.         Delmacro(i);
  559.         return;
  560.             }
  561.     (void) Findstr(nm, NULL, 0);
  562.         if (Sx >= 0) {
  563.             Delstr(Sx);
  564.             return;
  565.     }
  566.     Error(WARN, LINE, " no macro/string", NULL);
  567. }
  568.  
  569.  
  570. /*
  571.  * Rename macro or string - "^[.']rn"
  572.  */
  573.  
  574. #if    defined(_BCC)
  575. #pragma    argsused
  576. #endif    /* defined(_BCC) */
  577.  
  578.  
  579. static void
  580. nr_rn(line, brk)
  581.     unsigned char *line;
  582.     int brk;
  583. {
  584.     int i, j;            /* temporary indexes */
  585.     unsigned char nm[4], nm1[4];    /* name buffers */
  586.     unsigned char *s1;        /* temporary string pointer */
  587.  
  588.     if ((s1 = Field(2, line, 0)) == NULL ||  Asmname(s1, nm) == 0) {
  589.         Error(WARN, LINE, " no name", NULL);
  590.         return;
  591.     }
  592.     if ((s1 = Field(3, line, 0)) == NULL ||  Asmname(s1, nm1) == 0) {
  593.         Error(WARN, LINE, " no new name", NULL);
  594.         return;
  595.     }
  596.     if ((i = Findmacro(nm, 0)) >= 0) {
  597.         if ((j = Findmacro(nm1, 0)) >= 0)
  598.             Delmacro(j);
  599.         j = Findmacro(nm1, 1);
  600.         Macrotab[j].bx = Macrotab[i].bx;
  601.         Macrotab[i].bx = -1;
  602.         Macrotab[j].ct = Macrotab[i].ct;
  603.         Macrotab[i].ct = 0;
  604.         Delmacro(i);
  605.         return;
  606.     }
  607.     (void) Findstr(nm, NULL, 0);
  608.     if ((i = Sx) >= 0) {
  609.         (void) Findstr(nm1, Str[i].str, 1);
  610.         Delstr(i);
  611.         return;
  612.     }
  613.     if (Findmacro(nm1, 0) < 0)
  614.         (void) Findmacro(nm1, 1);
  615. }
  616.  
  617.  
  618. /*
  619.  * Remove register - "^[.']rr"
  620.  */
  621.  
  622. #if    defined(_BCC)
  623. #pragma    argsused
  624. #endif    /* defined(_BCC) */
  625.  
  626.  
  627. static void
  628. nr_rr(line, brk)
  629.     unsigned char *line;
  630.     int brk;
  631. {
  632.     int i;                /* temporary index */
  633.     unsigned char nm[4];        /* name buffer */
  634.  
  635.     if (Asmname(&line[3], nm) == 0) {
  636.         Error(WARN, LINE, " no name", NULL);
  637.         return;
  638.     }
  639.     if ((i = Findnum(nm, 0, 0)) < 0) {
  640.         Error(WARN, LINE, " no register", NULL);
  641.         return;
  642.     }
  643.     Delnum(i);
  644. }
  645.  
  646.  
  647. /*
  648.  * Resume space - "^[.']rs"
  649.  */
  650.  
  651. #if    defined(_BCC)
  652. #pragma    argsused
  653. #endif    /* defined(_BCC) */
  654.  
  655.  
  656. static void
  657. nr_rs(line, brk)
  658.     unsigned char *line;
  659.     int brk;
  660. {
  661.     Pass3(NOBREAK, (unsigned char *)"yesspace", -1, NULL, 0);
  662. }
  663.  
  664.  
  665. /*
  666.  * Three part title - "^[.'tl]"
  667.  */
  668.  
  669. #if    defined(_BCC)
  670. #pragma    argsused
  671. #endif    /* defined(_BCC) */
  672.  
  673.  
  674. static void
  675. nr_tl(line, brk)
  676.     unsigned char *line;
  677.     int brk;
  678. {
  679.     unsigned char buf[MAXLINE];    /* temporary buffer */
  680.     unsigned char *be, *bp;        /* buffer pointers */
  681.     int i, j, k, n;            /* temporary indexes */
  682.     unsigned char sep;        /* title separator */
  683.     unsigned char *tl, *tm, *tp,    /* title string pointers */
  684.               *tr, *ttl;
  685.  
  686.     for (bp = &line[3]; *bp == ' ' || *bp == '\t'; bp++)
  687.         ;
  688.     tl = ttl = Newstr(bp);
  689.     if ((sep = *tl++) == '\0') {
  690.  
  691. bad_title:
  692.         Error(WARN, LINE, " bad 3-part title", NULL);
  693.         Free(&ttl);
  694.         return;
  695.     }
  696.     for (tm = tl, tr = NULL; *tm && *tm != sep; tm++)
  697.         ;
  698.     if (*tm) {
  699.         *tm++ = '\0';
  700.         for (tr = tm; *tr && *tr != sep; tr++)
  701.             ;
  702.         if (*tr) {
  703.             *tr++ = '\0';
  704.             for (tp = tr; *tp && *tp != sep; tp++)
  705.                 ;
  706.             if (*tp)
  707.                 *tp = '\0';
  708.         }
  709.     }
  710.     i = LenprtHF(tl, Thispg, 0, NULL, 0) + LenprtHF(tm, Thispg, 0, NULL, 0)
  711.       + LenprtHF(tr, Thispg, 0, NULL, 0) + 2;
  712.     if (i > (sizeof(buf) - 2) || i > LT)
  713.         goto bad_title;
  714.     j = (LT - i - Pgoff) / 2 + 1;
  715.     n = LT - Pgoff - i - j + 2;
  716.     be = &buf[sizeof(buf) - 1];
  717.     for (bp = buf, k = 0; k < Pgoff; k++)
  718.         *bp++ = ' ';
  719.     if (tl)
  720.         (void) LenprtHF(tl, Thispg, 1, &bp, be - bp);
  721.     while (j--)
  722.         *bp++ = ' ';
  723.     if (tm)
  724.         (void) LenprtHF(tm, Thispg, 1, &bp, be - bp);
  725.     while (n--)
  726.         *bp++ = ' ';
  727.     if (tr)
  728.         (void) LenprtHF(tr, Thispg, 1, &bp, be - bp);
  729.     *bp = '\0';
  730.     Pass3(RAWLINE, (unsigned char *)"title3", -1, buf, 0);
  731.     Free(&ttl);
  732. }
  733.  
  734.  
  735. /*
  736.  * Message - "^[.']tm"
  737.  */
  738.  
  739. #if    defined(_BCC)
  740. #pragma    argsused
  741. #endif    /* defined(_BCC) */
  742.  
  743.  
  744. static void
  745. nr_tm(line, brk)
  746.     unsigned char *line;
  747.     int brk;
  748. {
  749.     Pass3(MESSAGE, Inname, -1, (line[3] == ' ') ? &line[4] : &line[3], NR);
  750. }
  751.  
  752.  
  753. /*
  754.  * Translate - "^[.']tr abcd..."
  755.  */
  756.  
  757. #if    defined(_BCC)
  758. #pragma    argsused
  759. #endif    /* defined(_BCC) */
  760.  
  761.  
  762. static void
  763. nr_tr(line, brk)
  764.     unsigned char *line;
  765.     int brk;
  766. {
  767.     unsigned char buf[MAXLINE];    /* temporary buffer */
  768.     int i, j;            /* temporary indexes */
  769.     unsigned char nm[4], nm1[4];    /* name buffers */
  770.     unsigned char *s1, *s2;        /* temporary string pointers */
  771.     int trin, trout;        /* types: 0 = char; 1 = named char */
  772.     unsigned char xbuf[MAXLINE];    /* temporary buffer */
  773.  
  774.     if (line[3] != ' ') {
  775.         Error(WARN, LINE, " unknown translation", NULL);
  776.         return;
  777.     }
  778.     for (s1 = &line[4]; *s1;) {
  779.         nm[1] = nm[2] = '\0';
  780.         s2 = s1 + 1;
  781.     /*
  782.      * Assemble the input value.
  783.      */
  784.         if (*s1 == '\\' && (*s2 == '*' || *s2 == '(')) {
  785.         if (*s2 == '(') {
  786.         /*
  787.          * Input is named character -- "\(xx".
  788.          */
  789.             trin = 1;
  790.             s1 = s2 + 1;
  791.             if ((nm[0] = *s1) != '\0') {
  792.             s1++;
  793.             if ((nm[1] = *s1) != '\0')
  794.                 s1++;
  795.             }
  796.         } else {
  797.         /*
  798.          * Input is interpolated string -- "\*x" or "\*(xx".
  799.          */
  800.             s1 = Asmcode(&s2, nm);
  801.             if (*s1)
  802.             s1++;
  803.             s2 = Findstr(nm, NULL, 0);
  804.             if (*s2 != '\0') {
  805.             if ((strlen((char *)s2) + strlen((char *)s1) + 1)
  806.             >= MAXLINE)
  807.                 Error(WARN, LINE, " string too long: ", (char *)nm);
  808.             else {
  809.                 (void) sprintf((char *)buf, "%s%s",
  810.                 (char *)s2, (char *)s1);
  811.                 (void) strcpy((char *)xbuf, (char *)buf);
  812.                 s1 = xbuf;
  813.             }
  814.             }
  815.             continue;
  816.         }
  817.         } else {
  818.  
  819.         /*
  820.          * Input is a simple character.
  821.          */
  822.         trin = 0;
  823.         if ((nm[0] = *s1) != '\0')
  824.             s1++;
  825.         }
  826.     /*
  827.      * Assemble the output value.
  828.      */
  829.  
  830. assemble_output:
  831.         nm1[1] = nm1[2] = '\0';
  832.         if (*s1 == '\0') {
  833.  
  834.         /*
  835.          * Supply a space if there is no output character.
  836.          */
  837.         trout = 0;
  838.         nm1[0] = ' ';
  839.         } else {
  840.         s2 = s1 + 1;
  841.         if (*s1 == '\\' && (*s2 == '(' || *s2 == '*')) {
  842.             if (*s2 == '(') {
  843.         /*
  844.          * The output is a named character -- "\(xx".
  845.          */
  846.             trout = 1;
  847.             s1 = s2 + 1;
  848.             if ((nm1[0] = *s1) != '\0') {
  849.                 s1++;
  850.                 if ((nm1[1] = *s1) != '\0')
  851.                 s1++;
  852.             }
  853.             } else {
  854.         /*
  855.          * The output is an interpolated string -- * "\*x" or "\*(xx".
  856.          */
  857.             s1 = Asmcode(&s2, nm1);
  858.             if (*s1)
  859.                 s1++;
  860.             s2 = Findstr(nm1, NULL, 0);
  861.             if (*s2 != '\0') {
  862.             /*
  863.              * Interpolate a string value.
  864.              */
  865.                 if ((strlen((char *)s2) + strlen((char *)s1) + 1)
  866.                 >= MAXLINE)
  867.                 Error(WARN, LINE, " string too long: ",
  868.                     (char *)nm);
  869.                 else {
  870.                 (void) sprintf((char *)buf, "%s%s", (char *)s2,
  871.                     (char *)s1);
  872.                 (void) strcpy((char *)xbuf, (char *)buf);
  873.                     s1 = xbuf;
  874.                 }
  875.             }
  876.             goto assemble_output;
  877.             }
  878.         } else {
  879.             trout = 0;
  880.             if ((nm1[0] = *s1) != '0')
  881.             s1++;
  882.             else
  883.             nm1[0] = ' ';
  884.         }
  885.         }
  886.     /*
  887.      * Do the translation.
  888.      */
  889.         switch (trin) {
  890.  
  891.         case 0:            /* simple char */
  892.         switch (trout) {
  893.  
  894.         case 0:            /* to simple char */
  895.             Trtbl[(int)nm[0]] = nm1[0];
  896.             break;
  897.         case 1:            /* to named char */
  898.             if ((i = Findchar(nm1, 0, NULL, 0)) < 0
  899.             ||  strlen((char *)Schar[i].str) != 1)
  900.             Error(WARN, LINE, " bad named character: ",
  901.                 (char *)nm1);
  902.             else
  903.             Trtbl[(int)nm[0]] = *(Schar[i].str);
  904.             break;
  905.         }
  906.         break;
  907.         case 1:            /* named char */
  908.         if ((i = Findchar(nm, 0, NULL, 0)) < 0)
  909.             Error(WARN, LINE, " unknown named character: ", (char *)nm);
  910.         else {
  911.             switch (trout) {
  912.  
  913.             case 0:        /* to simple char */
  914.             Free(&Schar[i].str);
  915.             Schar[i].str = Newstr(nm1);
  916.             Schar[i].len = 1;
  917.             break;
  918.             case 1:        /* to named char */
  919.             if ((j = Findchar(nm1, 0, NULL, 0)) < 0)
  920.                 Error(WARN, LINE, " unknown named character: ",
  921.                 (char *)nm1);
  922.             else
  923.                 (void) Findchar(nm, Schar[j].len, Schar[j].str, 1);
  924.             break;
  925.             }
  926.         }
  927.         break;
  928.         }
  929.     }
  930. }
  931.  
  932.  
  933. /*
  934.  * Initialization - "^[.']\^b (fh|HF|NH) [01]"
  935.  *
  936.  * fh = first page header status
  937.  * HF = header/footer status
  938.  * NH = initialize number headers
  939.  *
  940.  * Initialization - "^[.']\^b lf n" -- set footer line count to n
  941.  *
  942.  * Initialization - "^[.']\^b lh n" -- set header line count to n
  943.  */
  944.  
  945. #if    defined(_BCC)
  946. #pragma    argsused
  947. #endif    /* defined(_BCC) */
  948.  
  949.  
  950. static void
  951. nr_Ub(line, brk)
  952.     unsigned char *line;
  953.     int brk;
  954. {
  955.     int i;                /* temporary index */
  956.     unsigned char *s1, *s2;        /* temporary string pointers */
  957.  
  958.     if ((s1 = Field(2, line, 0)) == NULL)
  959.         return;
  960.     if ((s2 = Field(3, line, 0)) == NULL)
  961.         i = 0;
  962.     else
  963.         i = atoi((char *)s2);
  964.     if (s1[0] == 'f' && s1[1] == 'h')
  965.         Pass3(NOBREAK, (unsigned char *)"fph", -1, NULL, i);
  966.     else if (s1[0] == 'H' && s1[1] == 'F')
  967.         Hdft = i;
  968.     else if (s1[0] == 'N' && s1[1] == 'H') {
  969.         for (i = 0; i < MAXNHNR; i++)
  970.             Nhnr[i] = 0;
  971.     } else if (s1[0] == 'l' && s1[1] == 'f')
  972.         Botmarg = i;
  973.     else if (s1[0] == 'l' && s1[1] == 'h')
  974.         Topmarg = i;
  975.     else
  976.         Error(WARN, LINE, " unknown initialization", NULL);
  977. }
  978.  
  979.  
  980. /*
  981.  * Character definitions - "^[.']\^c"
  982.  */
  983.  
  984. #if    defined(_BCC)
  985. #pragma    argsused
  986. #endif    /* defined(_BCC) */
  987.  
  988.  
  989. static void
  990. nr_Uc(line, brk)
  991.     unsigned char *line;
  992.     int brk;
  993. {
  994.     unsigned char buf[MAXLINE];    /* temporary buffer */
  995.     int i;                /* temporary index */
  996.     unsigned char *s1, *s2, *s4,    /* temporary string pointers */
  997.               *s5;
  998.  
  999.     s2 = Field(2, line, 0);
  1000.     i = atoi((char *)Field(3, line, 0));
  1001.     s4 = Field(4, line, 0);
  1002.     if (i < 0 || i > MAXLINE/2 || *s2 == '\0') {
  1003.         Error(WARN, LINE, " bad character definition", NULL);
  1004.         return;
  1005.     }
  1006.     if (s4 == NULL)
  1007.         s4 = (unsigned char *)"";
  1008.     else if (*s4 == '"')
  1009.         s4++;
  1010.     s1 = buf;
  1011.     while ((s5 = (unsigned char *)strchr((char *)s4, '\\')) != NULL) {
  1012.         while (s5 > s4)
  1013.             *s1++ = *s4++;
  1014.         s4 = ++s5;
  1015.         if (*s5 == '\\')
  1016.             *s1++ = '\\';
  1017.         else if (*s5 == 'b')
  1018.             *s1++ = '\b';
  1019.         if (*s4)
  1020.             s4++;
  1021.     }
  1022.  
  1023. #if    defined(_BCC)
  1024. #pragma warn -pia
  1025. #endif    /* defined(_BCC) */
  1026.  
  1027.     while (*s1++ = *s4++)
  1028.         ;
  1029.  
  1030. #if    defined(_BCC)
  1031. #pragma warn +pia
  1032. #endif    /* defined(_BCC) */
  1033.  
  1034.     if (*s2 == 'h' && *(s2+1) == 'y')
  1035.         (void) Findhy(buf, i, 1);
  1036.     else
  1037.         (void) Findchar(s2, i, buf, 1);
  1038. }
  1039.  
  1040.  
  1041. /*
  1042.  * Font is OK - "[.']\^f <font_name_character>"
  1043.  */
  1044.  
  1045. #if    defined(_BCC)
  1046. #pragma    argsused
  1047. #endif    /* defined(_BCC) */
  1048.  
  1049.  
  1050. static void
  1051. nr_Uf(line, brk)
  1052.     unsigned char *line;
  1053.     int brk;
  1054. {
  1055.     int i;                /* temporary index */
  1056.  
  1057.     if (line[3] != '\0' && line[4] != '\0') {
  1058.         for (i = 0; Fcode[i].nm; i++) {
  1059.             if (line[4] == Fcode[i].nm) {
  1060.                 Fcode[i].status = '1';
  1061.                 return;
  1062.             }
  1063.         }
  1064.     }
  1065.     Error(WARN, LINE, " unknown font", NULL);
  1066. }
  1067.  
  1068.  
  1069. /*
  1070.  * Resolutions - "[.']\^r cpi horizontal vertical"
  1071.  */
  1072.  
  1073. #if    defined(_BCC)
  1074. #pragma    argsused
  1075. #endif    /* defined(_BCC) */
  1076.  
  1077.  
  1078. static void
  1079. nr_Ur(line, brk)
  1080.     unsigned char *line;
  1081.     int brk;
  1082. {
  1083.     unsigned char buf[MAXLINE];    /* temporary buffer */
  1084.     int i, j;            /* temporary indexes */
  1085.     double tval;            /* temporary value */
  1086.  
  1087.     if ((i = atoi((char *)Field(3, line, 0))) <= 0
  1088.     ||  (j = atoi((char *)Field(4, line, 0))) <= 0) {
  1089.         Error(WARN, LINE, " bad cpi resolutions", NULL);
  1090.         return;
  1091.     }
  1092.     tval = (double) (240.0 / (double) i);
  1093.     if (Findscale((int)'m', tval, 1) < 0)
  1094.         Error(FATAL, LINE, " missing Scal['m']", NULL);
  1095.     Scalen = tval;
  1096.     if (Scalen <= 0.0) {
  1097.         (void) sprintf((char *)buf, " bad Scale['n'] (%f)", Scalen);
  1098.         Error(FATAL, LINE, (char *)buf, NULL);
  1099.     }
  1100.     if (Findscale((int)'n', tval, 1) < 0)
  1101.         Error(FATAL, LINE, " missing Scale['n']", NULL);
  1102.     Scalev = (double) (240.0 / (double) j);
  1103.     if (Scalev <= 0.0) {
  1104.         (void) sprintf((char *)buf, " bad Scale['v'] (%f)", Scalen);
  1105.         Error(FATAL, LINE, (char *)buf, NULL);
  1106.     }
  1107.     if (Findscale((int)'v', Scalev, 1) < 0)
  1108.         Error(FATAL, LINE, " missing Scale['v']", NULL);
  1109. }
  1110.  
  1111.  
  1112. /*
  1113.  * Set line number and file name - "^[.']\^# <number> <file>"
  1114.  *
  1115.  * Lock line number and file name - "^[.']\^= <number> <file>"
  1116.  */
  1117.  
  1118. #if    defined(_BCC)
  1119. #pragma    argsused
  1120. #endif    /* defined(_BCC) */
  1121.  
  1122.  
  1123. static void
  1124. nr_UL(line, brk)
  1125.     unsigned char *line;
  1126.     int brk;
  1127. {
  1128.     unsigned char *s1;        /* temporary string pointer */
  1129.  
  1130.     if ((s1 = Field(2, line, 0)) != NULL)
  1131.         P2il = atoi((char *)s1) - 1;
  1132.     else
  1133.         P2il = 0;
  1134.     Lockil = (line[2] == '#') ? 0 : 1;
  1135.     Free(&P2name);
  1136.     if (Field(3, line, 1) != NULL) {
  1137.         P2name = F;
  1138.         F = NULL;
  1139.     } else
  1140.         P2name = NULL;
  1141. }
  1142.